import EditableTree from "../EditableTree";
import Tree from "../Tree";
import Spin from "../../Spin";
import { Searchfor, Setting } from "@ct0/icons";
import React, { useEffect, useMemo, useState } from "react";
import classNames from "classnames";
import type { SideTreeProps } from "./type";
import type { TreeDataType } from "../type";
import { useStyles } from "./styles";

export default SideTree;

function filterKeyword(
  keyword: string,
  data?: TreeDataType
): TreeDataType | undefined {
  if (!(Array.isArray(data) && data.length)) return undefined;

  const newData = [];

  for (const i of data) {
    const children = filterKeyword(keyword, i.children);
    if (
      String(i.title).toLowerCase().includes(keyword?.toLowerCase()) ||
      (children && children.length > 0)
    ) {
      newData.push({ ...i, count: i.count, children });
    }
  }

  return newData;
}

function SideTree({
  treeData: propsTreeData,
  title,
  defaultExpandAll,
  drawerTitle,
  editable,
  searchable = true,
  addChildText,
  total,
  checkable,
  disabledCheckAll,
  maxShowDeepth,
  maxCreateDeepth,
  highlightSelected,
  defaultSelected,
  selected,
  checked,
  defaultChecked,
  style,
  className,
  nodeTitleChangeValidator,
  nodeTitleRender,
  onSelect,
  onChange,
  onNodeTitleChange,
  onNodeRemove,
  onNodeAdd,
  onCheck,
  onRootNodeSelect,
}: SideTreeProps) {
  const classes = useStyles();

  const [treeData, setTreeData] = useState<TreeDataType>();
  const [filterWord, setFilterWord] = useState("");
  const [visiable, setVisiable] = useState(false);

  useEffect(() => {
    if (typeof propsTreeData == "function")
      propsTreeData().then((d) => setTreeData(d));
    else setTreeData(propsTreeData);
  }, [propsTreeData]);

  const filteredTreeData = useMemo(
    () => filterKeyword(filterWord, treeData) || [],
    [filterWord, treeData]
  );

  if (!treeData) return <Spin spinning></Spin>;

  return (
    <div className={classNames(classes.sideTree, className)} style={style}>
      <div className={classes.topbar}>
        {searchable && (
          <div className={classes.search}>
            <input
              placeholder="请输入要查找内容"
              onChange={(e) => setFilterWord(e.target.value)}
              className={classes.searchInput}
            />
            <span className={classes.searchIcon}>
              <Searchfor />
            </span>
          </div>
        )}
        {editable && (
          <>
            <div
              className={classes.editorIcon}
              onClick={() => setVisiable(true)}
            >
              <Setting />
            </div>
            <EditableTree
              total={total}
              drawerTitle={drawerTitle}
              addChildText={addChildText}
              nodeTitleChangeValidator={nodeTitleChangeValidator}
              visiable={visiable}
              onNodeRemove={onNodeRemove}
              onNodeAdd={onNodeAdd}
              onChange={onChange}
              onNodeTitleChange={onNodeTitleChange}
              treeData={treeData}
              title={title}
              maxShowDeepth={maxShowDeepth}
              maxCreateDeepth={maxCreateDeepth}
              onVisiable={setVisiable}
            />
          </>
        )}
      </div>
      <Tree
        checked={checked}
        selected={selected}
        defaultSelected={defaultSelected}
        title={title}
        total={total}
        maxShowDeepth={maxShowDeepth}
        maxCreateDeepth={maxCreateDeepth}
        checkable={checkable}
        disabledCheckAll={disabledCheckAll}
        defaultExpandAll={defaultExpandAll}
        defaultChecked={defaultChecked}
        expandAll={!!filterWord}
        highlightSelected={highlightSelected}
        nodeTitleRender={nodeTitleRender}
        treeData={filteredTreeData}
        className={classes.tree}
        onSelect={onSelect}
        onCheck={onCheck}
        onRootNodeSelect={onRootNodeSelect}
      />
    </div>
  );
}
